<?php

declare(strict_types=1);

namespace app\service\org;

use app\model\User;
use app\model\UserAuth;
use app\model\UserIdentity;
use app\model\UserProfile;
use app\service\user\CompanyVerificationService;
use InvalidArgumentException;
use think\facade\Db;

class OrgQuickCreateService
{
    public function __construct(
        private readonly CompanyVerificationService $companyVerificationService,
        private readonly OrganizationService $organizationService
    ) {
    }

    public function create(array $payload, int $operatorId): array
    {
        if ($operatorId <= 0) {
            throw new InvalidArgumentException('缺少当前操作员信息');
        }

        return Db::transaction(function () use ($payload, $operatorId) {
            $accountData = $payload['account'] ?? [];
            $user = $this->createAccount($accountData, $operatorId);

            $companyData = $payload['company'] ?? [];
            if (!is_array($companyData) || $companyData === []) {
                throw new InvalidArgumentException('请填写企业认证信息');
            }

            if (isset($companyData['license_raw']) && !isset($companyData['raw'])) {
                $companyData['raw'] = $companyData['license_raw'];
            }

            $regionId = isset($companyData['region_id']) ? (int) $companyData['region_id'] : 0;

            $company = $this->companyVerificationService->saveCompany($user->id, $companyData);

            $invoice = $payload['invoice'] ?? [];
            if (is_array($invoice) && $invoice !== []) {
                $invoice = $this->autoFillInvoice($invoice, $companyData);
                if (empty($invoice['invoice_title']) || empty($invoice['invoice_taxno'])) {
                    throw new InvalidArgumentException('请完善开票信息');
                }
                $this->companyVerificationService->saveInvoice($user->id, $invoice);
            }

            $addresses = $payload['addresses'] ?? [];
            if (!is_array($addresses) || $addresses === []) {
                throw new InvalidArgumentException('请至少填写一个收/发货地址');
            }
            $this->companyVerificationService->saveAddresses($user->id, ['addresses' => $addresses]);

            $result = $this->companyVerificationService->approveCompany($user->id, [
                'approved_by' => $operatorId,
                'region_id' => $regionId > 0 ? $regionId : null,
                'skip_notify' => true,
            ]);

            $freshUser = User::with('profile')->find((int) $user->id);

            return [
                'user' => $this->formatUser($freshUser ?? $user),
                'company' => $this->companyVerificationService->format($result['company']),
                'org' => $this->organizationService->format($result['org']),
            ];
        });
    }

    private function createAccount(array $account, int $operatorId): User
    {
        $phone = trim((string) ($account['phone'] ?? ''));
        if ($phone === '') {
            throw new InvalidArgumentException('手机号不能为空');
        }
        if (!preg_match('/^1\\d{10}$/', $phone)) {
            throw new InvalidArgumentException('手机号格式不正确');
        }

        if (User::where('phone', $phone)->find()) {
            throw new InvalidArgumentException('手机号已存在，请勿重复创建账号');
        }

        $password = (string) ($account['password'] ?? '');
        if (strlen($password) < 6) {
            throw new InvalidArgumentException('密码至少需要 6 位字符');
        }

        $nickname = isset($account['nickname']) ? trim((string) $account['nickname']) : '';
        $realName = isset($account['real_name']) ? trim((string) $account['real_name']) : '';

        $passwordHash = password_hash($password, PASSWORD_BCRYPT);

        $user = User::create([
            'phone' => $phone,
            'password_hash' => $passwordHash,
            'status' => 1,
            'register_channel' => 'system_audit',
            'invited_by' => $operatorId,
        ]);

        UserProfile::create([
            'user_id' => $user->id,
            'nickname' => $nickname !== '' ? $nickname : mb_substr($phone, -4),
            'real_name' => $realName,
        ]);

        UserAuth::create([
            'user_id' => $user->id,
            'identity_type' => UserAuth::TYPE_PASSWORD,
            'identifier' => $phone,
            'credential' => $passwordHash,
            'status' => 1,
        ]);

        UserAuth::create([
            'user_id' => $user->id,
            'identity_type' => UserAuth::TYPE_SMS,
            'identifier' => $phone,
            'credential' => null,
            'status' => 1,
        ]);

        UserIdentity::create([
            'user_id' => $user->id,
            'identity_type' => 'seller',
            'status' => 0,
            'invited_by' => $operatorId,
        ]);

        return $user;
    }

    private function autoFillInvoice(array $invoice, array $company): array
    {
        $title = trim((string) ($invoice['invoice_title'] ?? ''));
        $taxNo = trim((string) ($invoice['invoice_taxno'] ?? ''));

        if ($title === '' && isset($company['company_name'])) {
            $invoice['invoice_title'] = (string) $company['company_name'];
        }
        if ($taxNo === '' && isset($company['license_code'])) {
            $invoice['invoice_taxno'] = (string) $company['license_code'];
        }

        return $invoice;
    }

    private function formatUser(User $user): array
    {
        $profile = $user->profile;

        return [
            'id' => (int) $user->id,
            'phone' => (string) $user->phone,
            'status' => (int) $user->status,
            'nickname' => $profile->nickname ?? '',
            'real_name' => $profile->real_name ?? '',
            'invited_by' => $user->invited_by ? (int) $user->invited_by : null,
        ];
    }
}
